<?php

namespace app\common\service\Oss;

class Object extends Common {

    /**
     * 创建虚拟目录
     *
     * @param $dir 虚拟目录名
     * @return Boolean
     */
    public function createObjectDir($dir) {
        try {
            $this->_ossClient->createObjectDir($this->getBucketName(), $dir);
        } catch (OssException $e) {
            throw_exception($e->getMessage());
            return false;
        }
        return true;
    }

    /**
     * 把本地变量的内容到文件
     *
     * 简单上传,上传指定变量的内存值作为object的内容
     *
     * @param string $fileName 存储的文件名：photo1.png | 201602/photo1.png
     * @param string $content 文件流
     * @return Boolean
     */
    public function putObject($fileName ,&$content) {
        $options = array();
        try {
            $this->_ossClient->putObject($this->getBucketName(), $fileName, $content, $options);
        } catch (OssException $e) {
//            throw_exception($e->getMessage());
            throw_exception($e->getMessage(),'Think\\Exception',$e->getCode()); //测试Oss连接的错误号
            return false;
        }
        return true;
    }


    /**
     * 上传指定的本地文件内容
     *
     * @param string $fileName 存储的文件名：photo1.png | 201602/photo1.png
     * @param string $filePath 本地文件路径
     * @return Boolean
     */
    public function uploadFile($fileName, $filePath) {
        $options = array();
        try {
            $this->_ossClient->uploadFile($this->getBucketName(), $fileName, $filePath, $options);
        } catch (OssException $e) {
            throw_exception($e->getMessage());
            return false;
        }
        return true;
    }

    /**
     * 列出Bucket内所有目录和文件, 注意如果符合条件的文件数目超过设置的max-keys， 用户需要使用返回的nextMarker作为入参，通过
     * 循环调用ListObjects得到所有的文件，具体操作见下面的 listAllObjects 示例
     *
     * @param OssClient $this->_ossClient OssClient实例
     * @param string $bucket 存储空间名称
     * @return null
     */
    public function listObjects($prefix="" ,$maxkeys=1000) {
        $delimiter = '/';
        $nextMarker = '';
        $options = array(
            'delimiter' => $delimiter,
            'prefix' => $prefix,
            'max-keys' => $maxkeys,
            'marker' => $nextMarker,
        );
        try {
            $listObjectInfo = $this->_ossClient->listObjects($this->getBucketName(), $options);
        } catch (OssException $e) {
            throw_exception($e->getMessage());
            return false;
        }
        $data = [];
        $objectList = $listObjectInfo->getObjectList(); // 文件列表
        $prefixList = $listObjectInfo->getPrefixList(); // 目录列表
        if (!empty($objectList)) {
            foreach ($objectList as $objectInfo) {
                print($objectInfo->getKey() . "\n");
                $data['file'][] = $objectInfo->getKey();
            }
        }
        if (!empty($prefixList)) {
            foreach ($prefixList as $prefixInfo) {
                print($prefixInfo->getPrefix() . "\n");
                $data['dir'][] = $objectInfo->getPrefix();
            }
        }
        return $data;
    }

    /**
     * 列出Bucket内所有目录和文件， 根据返回的nextMarker循环得到所有Objects
     *
     * @param OssClient $this->_ossClient OssClient实例
     * @param string $bucket 存储空间名称
     * @return null
     */
    public function listAllObjects($prefix = "") {
        $delimiter = '/';
        $nextMarker = '';
        $maxkeys = 30;

        while (true) {
            $options = array(
                'delimiter' => $delimiter,
                'prefix' => $prefix,
                'max-keys' => $maxkeys,
                'marker' => $nextMarker,
            );
            var_dump($options);
            try {
                $listObjectInfo = $this->_ossClient->listObjects($this->getBucketName(), $options);
            } catch (OssException $e) {
                printf(__FUNCTION__ . ": FAILED\n");
                printf($e->getMessage() . "\n");
                return;
            }
            // 得到nextMarker，从上一次listObjects读到的最后一个文件的下一个文件开始继续获取文件列表
            $nextMarker = $listObjectInfo->getNextMarker();
            $listObject = $listObjectInfo->getObjectList();
            $listPrefix = $listObjectInfo->getPrefixList();
            var_dump(count($listObject));
            var_dump(count($listPrefix));
            if ($nextMarker === '') {
                break;
            }
        }
    }

    /**
     * 获取object的内容
     *
     * @param OssClient $this->_ossClient OssClient实例
     * @param string $bucket 存储空间名称
     * @param string $objectPath 对象路径
     * @return null
     */
    public function getObject($objectPath) {

        $options = array();
        try {
            $content = $this->_ossClient->getObject($this->getBucketName(), $objectPath, $options);
        } catch (OssException $e) {
            throw_exception($e->getMessage());
            return false;
        }
        return $content;
    }

    /**
     * get_object_to_local_file
     *
     * 获取object
     * 将object下载到指定的文件
     *
     * @param OssClient $this->_ossClient OssClient实例
     * @param string $bucket 存储空间名称
     * @return null
     */
    public function getObjectToLocalFile()
    {
        $object = "oss-php-sdk-test/upload-test-object-name.txt";
        $localfile = "upload-test-object-name.txt";
        $options = array(
            OssClient::OSS_FILE_DOWNLOAD => $localfile,
        );

        try {
            $this->_ossClient->getObject($this->getBucketName(), $object, $options);
        } catch (OssException $e) {
            printf(__FUNCTION__ . ": FAILED\n");
            printf($e->getMessage() . "\n");
            return;
        }
        print(__FUNCTION__ . ": OK, please check localfile: 'upload-test-object-name.txt'" . "\n");
        if (file_get_contents($localfile) === file_get_contents(__FILE__)) {
            print(__FUNCTION__ . ": FileContent checked OK" . "\n");
        } else {
            print(__FUNCTION__ . ": FileContent checked FAILED" . "\n");
        }
        if (file_exists($localfile)) {
            unlink($localfile);
        }
    }

    /**
     * 拷贝object
     * 当目的object和源object完全相同时，表示修改object的meta信息
     *
     * @param OssClient $this->_ossClient OssClient实例
     * @param string $bucket 存储空间名称
     * @return null
     */
    public function copyObject()
    {
        $fromBucket = $this->getBucketName();
        $fromObject = "oss-php-sdk-test/upload-test-object-name.txt";
        $toBucket = $bucket;
        $toObject = $fromObject . '.copy';
        $options = array();

        try {
            $this->_ossClient->copyObject($fromBucket, $fromObject, $toBucket, $toObject, $options);
        } catch (OssException $e) {
            printf(__FUNCTION__ . ": FAILED\n");
            printf($e->getMessage() . "\n");
            return;
        }
        print(__FUNCTION__ . ": OK" . "\n");
    }

    /**
     * 修改Object Meta
     * 利用copyObject接口的特性：当目的object和源object完全相同时，表示修改object的meta信息
     *
     * @param OssClient $this->_ossClient OssClient实例
     * @param string $bucket 存储空间名称
     * @return null
     */
    public function modifyMetaForObject()
    {
        $fromBucket = $this->getBucketName();
        $fromObject = "oss-php-sdk-test/upload-test-object-name.txt";
        $toBucket = $this->getBucketName();
        $toObject = $fromObject;
        $copyOptions = array(
            OssClient::OSS_HEADERS => array(
                'Cache-Control' => 'max-age=60',
                'Content-Disposition' => 'attachment; filename="xxxxxx"',
            ),
        );
        try {
            $this->_ossClient->copyObject($fromBucket, $fromObject, $toBucket, $toObject, $copyOptions);
        } catch (OssException $e) {
            printf(__FUNCTION__ . ": FAILED\n");
            printf($e->getMessage() . "\n");
            return;
        }
        print(__FUNCTION__ . ": OK" . "\n");
    }

    /**
     * 获取object meta, 也就是getObjectMeta接口
     *
     * @param OssClient $this->_ossClient OssClient实例
     * @param string $bucket 存储空间名称
     * @return null
     */
    public function getObjectMeta()
    {
        $object = "oss-php-sdk-test/upload-test-object-name.txt";
        try {
            $objectMeta = $this->_ossClient->getObjectMeta($this->getBucketName(), $object);
        } catch (OssException $e) {
            printf(__FUNCTION__ . ": FAILED\n");
            printf($e->getMessage() . "\n");
            return;
        }
        print(__FUNCTION__ . ": OK" . "\n");
        if (isset($objectMeta[strtolower('Content-Disposition')]) &&
            'attachment; filename="xxxxxx"' === $objectMeta[strtolower('Content-Disposition')]
        ) {
            print(__FUNCTION__ . ": ObjectMeta checked OK" . "\n");
        } else {
            print(__FUNCTION__ . ": ObjectMeta checked FAILED" . "\n");
        }
    }

    /**
     * 删除object
     *
     * @param OssClient $this->_ossClient OssClient实例
     * @param string $bucket 存储空间名称
     * @return null
     */
    public function deleteObject($object)
    {
        //$object = "oss-php-sdk-test/upload-test-object-name.txt";
        try {
            $this->_ossClient->deleteObject($this->getBucketName(), $object);
        } catch (OssException $e) {
            //printf(__FUNCTION__ . ": FAILED\n");
            //printf($e->getMessage() . "\n");
            //return;
            return FALSE;
        }
        //print(__FUNCTION__ . ": OK" . "\n");
        return TRUE;
    }


    /**
     * 批量删除object
     *
     * @param OssClient $this->_ossClient OssClient实例
     * @param string $bucket 存储空间名称
     * @return null
     */
    public function deleteObjects()
    {
        $objects = array();
        $objects[] = "oss-php-sdk-test/upload-test-object-name.txt";
        $objects[] = "oss-php-sdk-test/upload-test-object-name.txt.copy";
        try {
            $this->_ossClient->deleteObjects($this->getBucketName(), $objects);
        } catch (OssException $e) {
            printf(__FUNCTION__ . ": FAILED\n");
            printf($e->getMessage() . "\n");
            return;
        }
        print(__FUNCTION__ . ": OK" . "\n");
    }

    /**
     * 判断object是否存在
     *
     * @param OssClient $this->_ossClient OssClient实例
     * @param string $bucket 存储空间名称
     * @return null
     */
    public function doesObjectExist($object)
    {
        //$object = "oss-php-sdk-test/upload-test-object-name.txt";
        try {
            $exist = $this->_ossClient->doesObjectExist($this->getBucketName(), $object);
        } catch (OssException $e) {
            //printf(__FUNCTION__ . ": FAILED\n");
            //printf($e->getMessage() . "\n");
            //return;
            return $e->getMessage();
        }
        //print(__FUNCTION__ . ": OK" . "\n");
        return $exist;
    }

}
